<template>
  <t-card :bordered="!isDiaog" :class="{ isDalog: isDiaog }">
    <t-space direction="vertical" style="width: 100%">
      <common-search-bar :data="searchBarData" @search="commonIns.tableFn.search" @reset="commonIns.tableFn.reset" />

      <common-action-bar :data="actionBarData" @action="onAction" />

      <t-table
        v-if="viewtype === 'list'"
        row-key="id"
        :data="list"
        :columns="columns"
        :loading="isLoading"
        :pagination="pagination"
        :selected-row-keys="selectedRowKeys"
        resizable
        bordered
        stripe
        @page-change="commonIns.tableFn.onPageChange"
        @select-change="commonIns.tableFn.onSelectChange"
      >
      </t-table>
      <template v-else>
        <div class="viewer-list">
          <t-image-viewer v-for="(v, k) in list" :key="k" :images="[baseUrl + v.url]">
            <template #trigger="{ open }">
              <div class="viewer-item" :class="{ active: selectedRowKeys.includes(v.id) }" @click="onCheck(v)">
                <t-image :src="baseUrl + v.url" fit="contain" style="width: 100%; height: 100%" />
                <t-radio v-if="isDiaog" :checked="selectedRowKeys.includes(v.id)" class="radio" />
                <t-popup class="placement top center" placement="top" show-arrow destroy-on-close>
                  <t-icon name="info-circle-filled" size="medium" color="#ddd" class="info" />
                  <template #content>
                    <div>{{ t('pages.attachement.path') }}: {{ v.url }}</div>
                    <div>{{ t('pages.attachement.size') }}: {{ v.size }}</div>
                    <div>{{ t('pages.attachement.type') }}: {{ v.mimetype }}</div>
                    <div>{{ t('common.createBy') }}: {{ v.operator.username }}</div>
                    <div>{{ t('common.createAt') }}: {{ v.createdAt }}</div>
                  </template>
                </t-popup>
                <t-space align="center" class="action">
                  <span @click="open">预览</span>
                  <span>|</span>
                  <span @click.stop="onUploadRemove(v)">删除</span>
                </t-space>
              </div>
            </template>
          </t-image-viewer>
        </div>

        <t-pagination
          v-model:page-size="pagination.pageSize"
          :current="pagination.current"
          :page-size-options="pagination.pageSizeOptions"
          :total="pagination.total"
          @change="commonIns.tableFn.onPageChange"
        />
      </template>
    </t-space>
  </t-card>
</template>

<script setup lang="ts">
import dayjs from 'dayjs';
import { TableRowData } from 'tdesign-vue-next';
import { onMounted, ref, watch } from 'vue';

import $api from '@/api';
import CommonActionBar from '@/components/common-action-bar/index.vue';
import CommonSearchBar from '@/components/common-search-bar/index.vue';
import { isLoading, useCommon } from '@/hooks/common';
import { t } from '@/locales';

import { ACTION_BAR_DATA, COLUMNS, SEARCH_BAR_DATA } from './constants';

// 作为弹窗组件，需要传递是否是否弹窗组件
const props = defineProps({
  // 是否弹窗组件调用
  isDiaog: {
    type: Boolean,
    default: false,
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false,
  },
});

const baseUrl = import.meta.env.VITE_API_URL;
const API = $api.content.attachement;

const searchBarData = ref([...SEARCH_BAR_DATA]);
const actionBarData = ref([...ACTION_BAR_DATA]);

const columns = ref(...[COLUMNS]);

watch(
  () => props.isDiaog,
  () => {
    if (props.isDiaog) {
      columns.value.unshift({ colKey: 'row-select', type: props.multiple ? 'multiple' : 'single' });
    } else if (columns.value[0].colKey === 'row-select') {
      columns.value.shift();
    }
  },
  {
    immediate: true,
  },
);

const { list, pagination, selectedRowKeys, ...commonIns } = useCommon({
  API,
  formatSearch: (data: Recordable) => {
    if (data.size) {
      data.size = data.size.split('-');
    }

    if (data.createdAt.length) {
      const date = data.createdAt;
      data.createdAt = [
        dayjs(`${date[0]} 00:00:00`).format('YYYY-MM-DD HH:mm:ss'),
        dayjs(`${date[1]} 23:59:59`).format('YYYY-MM-DD HH:mm:ss'),
      ];
    }
    return data;
  },
});

const viewtype = ref('list');
const onAction = (type: string, val: string) => {
  if (type === 'radio-change') {
    viewtype.value = val;
    if (val === 'album') {
      pagination.value.pageSize = 50;
    } else {
      pagination.value.pageSize = 10;
    }
  }

  commonIns.tableFn.getList();
};

const getEnums = async () => {
  const filesize = await $api.system.dict.values('filesize');
  searchBarData.value[1].options = filesize;

  const manager = await $api.system.manager.list();

  const options = manager.items.map((v: Recordable) => {
    return {
      label: v.username,
      value: v.id,
    };
  });
  searchBarData.value[2].options = options;
};

const onUploadRemove = async (item: TableRowData) => {
  commonIns.tableFn.delete(item);
  if (selectedRowKeys.value[0] === item.id) {
    selectedRowKeys.value = [];
  }
};

const onCheck = (item: TableRowData) => {
  if (!props.isDiaog) {
    return;
  }
  // 多选
  if (props.multiple) {
    const isHas = selectedRowKeys.value.includes(item.id);
    if (isHas) {
      const index = selectedRowKeys.value.findIndex((v) => v === item.id);
      selectedRowKeys.value.splice(index, 1);
    } else {
      selectedRowKeys.value.push(item.id);
    }
  } else {
    // 单选
    selectedRowKeys.value = [item.id];
  }
};

const getChecked: Recordable = () => {
  if (!selectedRowKeys.value.length) {
    return undefined;
  }

  return list.value.find((v) => v.id === selectedRowKeys.value[0]);
};

onMounted(() => {
  getEnums();
  commonIns.tableFn.getList();
});

defineExpose({ getChecked });
</script>

<style lang="less" scoped>
.isDalog :deep(.t-card__body) {
  padding: 0;
}
.viewer-list {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
}
.viewer-item {
  width: 120px;
  height: 120px;
  position: relative;
  overflow: hidden;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
  &.active {
    border-color: var(--td-brand-color);
    box-shadow: 0 0 1px 1px var(--td-brand-color);
  }
  .action {
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 2;
    color: #fff;
    justify-content: center;
    transition: 0.2s;
    opacity: 0;
  }
  &:hover .action {
    opacity: 1;
  }

  .radio {
    position: absolute;
    top: 5px;
    left: 10px;
    z-index: 3;
  }

  .info {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 3;
  }
}
</style>
